package main

// Logrus是Go（golang）的结构化logger，与标准库logger完全API兼容。

// 它有以下特点：

// 完全兼容标准日志库，拥有七种日志级别：Trace, Debug, Info, Warning, Error, Fataland Panic。
// 可扩展的Hook机制，允许使用者通过Hook的方式将日志分发到任意地方，如本地文件系统，logstash，elasticsearch或者mq等，或者通过Hook定义日志内容和格式等
// 可选的日志输出格式，内置了两种日志格式JSONFormater和TextFormatter，还可以自定义日志格式
// Field机制，通过Filed机制进行结构化的日志记录
// 线程安全

// 安装命令:go get github.com/sirupsen/logrus
// 案例

import (
	"os"

	"log/syslog"

	"github.com/sirupsen/logrus"
	log "github.com/sirupsen/logrus"
	logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
	airbrake "gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "airbrake"
)

// 基本用法
func Log_1() {
	log.WithFields(log.Fields{
		"animal": "dog",
	}).Info("一条舔狗出现了")
}

// 进阶用法
func Log_2() {
	var log = log.New()
	// 设置日志输出为os.Stdout
	log.Out = os.Stdout
	// 可以设置像文件等任意`io.Writer`类型作为日志输出
	// file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	// if err == nil {
	//  log.Out = file
	// } else {
	//  log.Info("Failed to log to file, using default stderr")
	// }
	log.WithFields(logrus.Fields{
		"animal": "dog",
		"size":   10,
	}).Info("一群舔狗出现了...")

}

// logrus 七个日志级别
func Log_Infos() {
	// 设置日志级别 显示对应级别的日志
	// 会记录info及以上级别 (warn, error, fatal, panic)
	log.SetLevel(log.InfoLevel)
	log.Trace("Somethis very low level")
	log.Debug("UseFul debugging information")
	log.Warn("You should probably take a look at this.")
	log.Error("Something failed but I'm not quitting")
	// 记录完日志会调用os.Exit(1)
	log.Fatal("Bye")
	// 记录完之日会调用 panic()
	log.Panic("i'm bailing.")
}

// Hook 级别的日志钩子
// 你可以添加日志级别的钩子（Hook）。
// 例如，向异常跟踪服务发送Error、Fatal和Panic、信息到StatsD或同时将日志发送到多个位置，例如syslog。
// Logrus配有内置钩子。在init中添加这些内置钩子或你自定义的钩子：
func init() {
	// Use the Airbrake hook to report errors that have Error severity or above to
	// an exception tracker. You can create custom hooks, see the Hooks section.
	log.AddHook(airbrake.NewHook(123, "xyz", "production"))

	hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
	if err != nil {
		log.Error("Unable to connect to local syslog daemon")
	} else {
		log.AddHook(hook)
	}
}

// 格式化
// logrus内置以下两种日志格式化程序：
// logrus.TextFormatter logrus.JSONFormatter
// 还支持一些第三方的格式化程序，详见项目首页。

// 记录函数名
// 如果你希望将调用的函数名添加为字段，请通过以下方式设置：
// log.SetReportCaller(true)
// 这会将调用者添加为”method”，如下所示：

// {"animal":"penguin","level":"fatal","method":"github.com/sirupsen/arcticcreatures.migrate","msg":"a penguin swims by",
// "time":"2014-03-10 19:57:38.562543129 -0400 EDT"}
// 默认的logger在并发写的时候是被mutex保护的，比如当同时调用hook和写log时mutex就会被请求，有另外一种情况，文件是以appending mode打开的， 此时的并发操作就是安全的，可以用logger.SetNoLock()来关闭它。

func main() {
	Log_1()
	Log_2()
	Log_Infos()
}
